package com.songlanyun.modules.skus.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.songlanyun.common.drive.Validator;
import com.songlanyun.common.exception.RRException;
import com.songlanyun.common.supplychainapi.goods.model.GoodsDetailResult;
import com.songlanyun.common.validator.ValidatorUtils;
import com.songlanyun.common.validator.group.AddGroup;
import com.songlanyun.common.validator.group.UpdateGroup;
import com.songlanyun.modules.exception.GoodsExceptionEnum;
import com.songlanyun.modules.goods.model.values.SkuItem;
import com.songlanyun.modules.group.entity.ProductGoodsGroupEntity;
import com.songlanyun.modules.shop.service.ShopService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.songlanyun.common.utils.PageUtils;
import com.songlanyun.common.utils.Query;

import com.songlanyun.modules.skus.dao.ProductSkusDao;
import com.songlanyun.modules.skus.entity.ProductSkusEntity;
import com.songlanyun.modules.skus.service.ProductSkusService;

/**
 * 商品规格
 */
@Service("productSkusService")
public class ProductSkusServiceImpl extends ServiceImpl<ProductSkusDao, ProductSkusEntity> implements ProductSkusService {
    @Autowired
    private ShopService shopService;
    /**
     * 根据商品规格实例来创建规格
     * @param entity
     * @return
     */
    @Override
    public ProductSkusEntity create(ProductSkusEntity entity) {
        ValidatorUtils.validateEntity(entity);
        validateNameExists(entity);
        validateParent(entity);
        this.baseMapper.insert(entity);
        return entity;
    }

    /**
     * 根据商品规格实例来修改商品规格
     * @param entity
     * @return
     */
    @Override
    public ProductSkusEntity modify(ProductSkusEntity entity) {
        ValidatorUtils.validateEntity(entity);
        validateNameExistsForUpdate(entity);
        validateUpdateParentSafe(entity);

        this.baseMapper.updateById(entity);
        return this.getById(entity.getId());
    }

    /**
     * 根据商品规格标识删除商品规格
     * @param id
     * @return
     */
    @Override
    public void remove(Long id) {
        validateRemoveSafe(id);
        this.removeById(id);
    }

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<ProductSkusEntity> page = this.page(
                new Query<ProductSkusEntity>().getPage(params),
                new QueryWrapper<ProductSkusEntity>()
        );

        return new PageUtils(page);
    }


    /**
     * 查询商家创建的所有规格属性
     * @param shopId
     * @return
     */
    @Override
    public List<Map<String, Object>> getAllSku(Long shopId) {
        QueryWrapper<ProductSkusEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("shop_id",shopId);
        List<ProductSkusEntity> list = this.list(queryWrapper);
        return makeGoodsGroupTree(list, 0);
    }

    private List<Map<String, Object>> makeGoodsGroupTree(List<ProductSkusEntity> skuList, long parentId) {
        List<Map<String, Object>> list = new ArrayList<>();
        for (ProductSkusEntity group : skuList) {
            if (group.getParentSkuId() == parentId) {
                Map<String, Object> map = new LinkedHashMap<>();
                map.put("id", group.getId());
                map.put("name", group.getName());
                map.put("parent_sku_id", group.getParentSkuId());
                map.put("order_index", group.getOrderIndex());
                map.put("shop_id", group.getShopId());
                if(parentId==0L)
                {
                    map.put("children", makeGoodsGroupTree(skuList, group.getId()));
                }

                list.add(map);
            }
        }

        list.sort(new Comparator<Map<String, Object>>() {
            @Override
            public int compare(Map<String, Object> o1, Map<String, Object> o2) {
                if ((int) o1.get("order_index") <= (int) o2.get("order_index")) {
                    return 1;
                } else {
                    return -1;
                }
            }
        });
        return list;
    }

    /**
     * 查询商家创建的某个规格的子规格
     * @param shopId
     * @param parentId
     * @return
     */
    @Override
    public List<ProductSkusEntity> getChildren(Long shopId, Long parentId) {

        QueryWrapper<ProductSkusEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_sku_id",parentId);
        queryWrapper.eq("shop_id",shopId);
        List<ProductSkusEntity> entities = this.baseMapper.selectList(queryWrapper);
        return entities;
    }

    @Override
    public List<ProductSkusEntity> selectByIds(Long shopId,Long[] ids) {
        List<ProductSkusEntity> list = this.list(new LambdaQueryWrapper<ProductSkusEntity>()
                .eq(ProductSkusEntity::getShopId,shopId)
                .in(ProductSkusEntity::getId, Arrays.asList(ids)));
        list.forEach(ProductSkusEntity::loadChildren);
        return list;
    }

    /**
     * 查询商家创建的一级规格属性
     * @param shopId
     * @return
     */
    @Override
    public List<ProductSkusEntity> getTopSku(Long shopId) {
        return this.getChildren(shopId,0L);
    }

    /**
     * 查询商家创建的某个规格
     * @param shopId
     * @param id
     * @return
     */
    @Override
    public ProductSkusEntity getByShopIdAndId(Long shopId, Long id) {
        return this.baseMapper.getByShopIdAndId(shopId,id);
    }

    /**
     * 商家创建的某个规格
     * @param shopId
     * @param entity
     * @return
     */
    @Override
    public ProductSkusEntity add(Long shopId, ProductSkusEntity entity) {
        shopService.loadShopBy(shopId,true);
        entity.setShopId(shopId);
        return this.create(entity);
    }

    /**
     * 商家修改的某个规格
     * @param shopId
     * @param entity
     * @return
     */
    @Override
    public ProductSkusEntity update(Long shopId, ProductSkusEntity entity) {
        shopService.loadShopBy(shopId,true);
        validateShopSafe(shopId,entity.getId());
        entity.setShopId(shopId);
        return this.modify(entity);
    }



    /**
     * 商家删除的某个规格
     * @param shopId
     * @param id
     */
    @Override
    public void deleteByShopIdAndId(Long shopId, Long id) {
        shopService.loadShopBy(shopId,true);
        validateShopSafe(shopId,id);
        this.remove(id);
    }

    @Override
    public SkuItem getOrCreate(Long shopId, GoodsDetailResult.Name name, Long parentId) {
        ProductSkusEntity productSkusEntity = this.baseMapper.selectOne(new LambdaQueryWrapper<ProductSkusEntity>()
                .eq(ProductSkusEntity::getShopId, shopId)
                .eq(ProductSkusEntity::getParentSkuId, parentId)
                .eq(ProductSkusEntity::getName, name.getName())
                .last("limit 1"));
        if(ObjectUtil.isNull(productSkusEntity))
        {
            productSkusEntity    = new ProductSkusEntity();
            productSkusEntity.setName(name.getName());
            productSkusEntity.setShopId(shopId);
            productSkusEntity.setOrderIndex(0);
            productSkusEntity.setParentSkuId(parentId);
            this.create(productSkusEntity);
        }
        SkuItem item = new SkuItem();
        item.setId(productSkusEntity.getId());
        item.setName(productSkusEntity.getName());
        item.setThirdId(name.getId());
        return item;
    }

    @Override
    public SkuItem getOrCreate(Long shopId, GoodsDetailResult.Value value, Long parentId) {
        ProductSkusEntity productSkusEntity = this.baseMapper.selectOne(new LambdaQueryWrapper<ProductSkusEntity>()
                .eq(ProductSkusEntity::getShopId, shopId)
                .eq(ProductSkusEntity::getParentSkuId, parentId)
                .eq(ProductSkusEntity::getName, value.getName())
                .last("limit 1"));
        if(ObjectUtil.isNull(productSkusEntity))
        {
            productSkusEntity    = new ProductSkusEntity();
            productSkusEntity.setName(value.getName());
            productSkusEntity.setShopId(shopId);
            productSkusEntity.setParentSkuId(parentId);
            productSkusEntity.setOrderIndex(0);
            this.create(productSkusEntity);
        }
        SkuItem item = new SkuItem();
        item.setId(productSkusEntity.getId());
        item.setName(productSkusEntity.getName());
        item.setThirdId(value.getId());
        return item;
    }


    /**
     * 验证规格的名称不能重复
     * @param entity
     */
    private void validateNameExists(ProductSkusEntity entity) {
        ProductSkusEntity target = this.baseMapper.getByName(entity.getShopId(),entity.getParentSkuId(),entity.getName());
        if (target != null && !target.equals(entity)) {

            throw new RRException(GoodsExceptionEnum.PRODUCT_SKU_NAME_REPEAT);
        }
    }

    private void validateNameExistsForUpdate(ProductSkusEntity entity) {
        ProductSkusEntity obj = this.getById(entity.getId());
        if (obj == null) {
            throw new RRException(GoodsExceptionEnum.PRODUCT_SKU_NAME_REPEAT);
        }
        ProductSkusEntity target = this.baseMapper.getByName(entity.getShopId(),obj.getParentSkuId(),entity.getName());
        if (target != null && !target.equals(entity)) {

            throw new RRException(GoodsExceptionEnum.PRODUCT_SKU_NAME_REPEAT);
        }
    }


    /**
     * 验证规格的商家店铺安全性，不是自己商家的sku不能操作
     * @param shopId
     * @param id
     */
    private void validateShopSafe(Long shopId, Long id)
    {
        ProductSkusEntity load = this.getById(id);
        if(load!=null&& !load.getShopId().equals(shopId))
        {
            throw new RRException(GoodsExceptionEnum.PRODUCT_SKU_SHOP_SAFE);
        }
    }

    /**
     * 验证id对应的规格是否存在
     *
     * @param id
     */
    private void validateExists(Long id) {
        ProductSkusEntity entity = this.getById(id);
        if (entity == null) {
            throw new RRException(GoodsExceptionEnum.PRODUCT_SKU_NAME_REPEAT);
        }
    }

    /**
     * 删除规格时的安全验证
     * 要删除的规格不存在不能删除
     * 下面还有子规格的不能删除
     * @param id
     */
    private void validateRemoveSafe(Long id) {
        ProductSkusEntity entity = this.getById(id);
        if (entity == null) {
            throw new RRException(GoodsExceptionEnum.PRODUCT_SKU_NOT_EXISTS);
        }

        if(entity.loadChildren().size()>0)
        {
            throw new RRException(GoodsExceptionEnum.PRODUCT_SKU_REMOVE_SAFE);
        }
    }

    /**
     * 1、如果新增时设置的父级对象不存在报错,
     * 2、如果新增加选择的父级是二级报错，只能有两级规格（名称和值）
     * @param entity
     */
    private void validateParent(ProductSkusEntity entity) {
        if(entity.getParentSkuId()==0L) return ;
        ProductSkusEntity parent = this.baseMapper.getByShopIdAndId(entity.getShopId(),entity.getParentSkuId());
        if (parent == null) {
            throw new RRException(GoodsExceptionEnum.PRODUCT_SKU_PARENT_NOT_EXISTS);
        }

        if (parent.getParentSkuId() > 0) {
            throw new RRException(GoodsExceptionEnum.PRODUCT_SKU_SECOND_SAFE);
        }
    }

    /**
     * 1、商品规格的父级不存在报错
     * 2、商品规格的父级还有父级报错
     * 3、自己有父级，同时自己还有下级规格报错，系统只需要两级
     * @param entity
     */
    private void  validateUpdateParentSafe(ProductSkusEntity entity)
    {
        /**
         * 如果要修改的父级属性不大于0
         */
        if(entity.getParentSkuId()!=null && entity.getParentSkuId()>0)
        {
            //如果自己还有下级，说明现在成了三级，但是系统只需要两级，所以要报错

            ProductSkusEntity parent = this.baseMapper.getByShopIdAndId(entity.getShopId(),entity.getParentSkuId());
            if(parent==null)
            {
                throw new RRException(GoodsExceptionEnum.PRODUCT_SKU_PARENT_NOT_EXISTS);
            }

            if(parent.getParentSkuId()>0)
            {
                throw new RRException(GoodsExceptionEnum.PRODUCT_SKU_SECOND_SAFE);
            }

            if(entity.getParentSkuId()==entity.getId())
            {
                throw new RRException(GoodsExceptionEnum.PRODUCT_SKU_SELECT_SELF);
            }

            if(entity.loadChildren().size()>0)
            {
                throw new RRException(GoodsExceptionEnum.PRODUCT_SKU_SECOND_SAFE);
            }


        }
    }
}
